package com.arpa.oms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.PartyCacheDO;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.oms.service.IMoveService;
import com.arpa.wms.cache.CustomerCache;
import com.arpa.wms.cache.GoodsCache;
import com.arpa.wms.cache.LocationCache;
import com.arpa.wms.cache.SupplierCache;
import com.arpa.wms.common.util.OrderIdGeneratorUtil;
import com.arpa.wms.domain.dto.WmsTaskDTO;
import com.arpa.wms.domain.entity.*;
import com.arpa.wms.domain.enums.*;
import com.arpa.wms.domain.vo.*;
import com.arpa.wms.mapper.ReceiveItemMapper;
import com.arpa.wms.mapper.ReceiveMapper;
import com.arpa.wms.mapper.WmsTaskMapper;
import com.arpa.wms.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.arpa.wms.domain.consts.NumConst.NUM_ONE;
import static com.arpa.wms.domain.consts.NumConst.NUM_ZERO;

/**
 * <p>
 * 任务中心 Service实现类
 * </p>
 *
 * @author LEO
 * @since 2020-10-09
 */
@Service
@Log4j2
public class WmsTaskServiceImpl extends ServiceImpl<WmsTaskMapper, WmsTask> implements IWmsTaskService {


    @Resource
    private ReceiveMapper receiveMapper;

    @Resource
    private ReceiveItemMapper receiveItemMapper;

    private final IPutawayService putawayService;

    private final IPutawayItemService putawayItemService;

    private final GoodsCache goodsCache;

    private final SupplierCache supplierCache;

    private final IPickingService pickingService;

    private final IMoveService moveService;

    private final IWmsTaskItemService wmsTaskItemService;

    private final PartyCache partyCache;

    private final LocationCache locationCache;

    private final CustomerCache customerCache;

    private final IOutboundService outboundService;

    private final ICountingService countingService;

    private final IOutboundItemService outboundItemService;

    @Autowired
    @Lazy
    private IPutawayRegisterService putawayRegisterService;

    @Autowired
    @Lazy
    private IDeliveryService deliveryService;

    public WmsTaskServiceImpl(IPickingService pickingService,
                              ICountingService countingService,
                              IPutawayService putawayService,
                              IPutawayItemService putawayItemService,
                              GoodsCache goodsCache,
                              SupplierCache supplierCache,
                              IMoveService moveService,
                              IWmsTaskItemService wmsTaskItemService,
                              PartyCache partyCache,
                              LocationCache locationCache,
                              CustomerCache customerCache,
                              IOutboundService outboundService,
                              IOutboundItemService outboundItemService) {
        this.pickingService = pickingService;
        this.countingService = countingService;
        this.putawayService = putawayService;
        this.putawayItemService = putawayItemService;
        this.goodsCache = goodsCache;
        this.supplierCache = supplierCache;
        this.moveService = moveService;
        this.wmsTaskItemService = wmsTaskItemService;
        this.partyCache = partyCache;
        this.locationCache = locationCache;
        this.customerCache = customerCache;
        this.outboundService = outboundService;
        this.outboundItemService = outboundItemService;
    }



    /**
     * 查询列表
     *
     * @param wmsTaskDTO
     * @return
     */
    @Override
    public List<WmsTaskVO> queryList(WmsTaskDTO wmsTaskDTO) {
        wmsTaskDTO.setGroupCode(UserUtil.getBranchCode());
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StrUtil.isNotEmpty(wmsTaskDTO.getSortField())) {
            wmsTaskDTO.setSortField(CommonUtil.camel2Underline(wmsTaskDTO.getSortField()));
        }
        List<WmsTaskVO> tasks = baseMapper.queryList(wmsTaskDTO);
        tasks.stream().forEach(e -> {
            if (StrUtil.isNotBlank(e.getCustomerCode())) {
                e.setCustomerName(customerCache.translate(e.getCustomerCode()));
            }
            if (StrUtil.isNotBlank(e.getLocation())) {
                e.setLocationName(locationCache.translate(e.getLocation()));
            }
        });
        return tasks;
    }

    /**
     * 查询合计,包含总数
     *
     * @param wmsTaskDTO
     * @return
     */
    @Override
    public WmsTaskVO queryListSum(WmsTaskDTO wmsTaskDTO) {
        WmsTaskVO task = baseMapper.queryListSum(wmsTaskDTO);
        return task;
    }

    /**
     * 下发任务
     *  @param taskType   任务类型 任务类型：RECEIVE收货、PUTAWAY上架、PICKING拣货、CHECK复核、INVENTORY盘点、MOVE移位
     * @param sourceCode 关联单号
     * @param userCode
     */
    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public Future<Boolean> issue(final WmsTaskTypeEnum taskType,  final String sourceCode, final String userCode, final String groupCode) {
        switch (taskType) {
            case RECEIVE: {
                //收货
                Receive receive = receiveMapper.selectOne(new QueryWrapper<Receive>().lambda().eq(Receive::getCode, sourceCode).eq(Receive::getGroupCode,groupCode));
                if (ObjectUtil.isNull(receive)) {
                    log.error("收货任务下发失败，没有找到收货单【{}】", sourceCode);
                    throw new ServiceException("任务下发失败，没有找到收货单【" + sourceCode + "】");
                }
                if (receive.getIssue() == 1) {
                    log.error("收货任务下发失败，收货单【{}】已下发", sourceCode);
                    throw new ServiceException("任务下发失败，收货单【" + sourceCode + "】已下发");
                }

                //TODO 需要判断收货单状态是否可以下发
                if (!StrUtil.equals(ReceiveStatusEnum.WAITING_RECEIVE.getValue(), receive.getStatus())) {
                    // 0:新增；1：作废；2：待收货；3：部分收货；4：收货完成
                    String statusStr = ReceiveStatusEnum.translate(receive.getStatus());

                    throw new ServiceException("任务下发失败，收货单【" + sourceCode + "】" + statusStr);
                }

                List<ReceiveItem> receiveItems = receiveItemMapper.selectList(new QueryWrapper<ReceiveItem>().lambda()
                        .eq(ReceiveItem::getReceiveCode, receive.getCode())
                        .eq(ReceiveItem::getGroupCode,groupCode)
                );
                //计算商品数量
                BigDecimal goodsQuantity = receiveItems.stream().map(ReceiveItem::getPlanQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                //计算商品种类数量
                int goodsTypeQuantity = receiveItems.stream().collect(Collectors.groupingBy(ReceiveItem::getGoodsCode)).size();
                WmsTask task = new WmsTask();
                task.setCode(sourceCode + "01");
                task.setGroupCode(receive.getGroupCode());
                task.setWarehouseCode(receive.getWarehouseCode());
                task.setGoodsQuantity(goodsQuantity);
                task.setGoodsTypeQuantity(goodsTypeQuantity);
                task.setTaskType(taskType);
                task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                task.setSourceCode(sourceCode);
                task.setCreatedBy(userCode);
                task.setCreatedName(partyCache.translate(userCode));
                task.setModifiedBy(userCode);
                task.setModifiedName(partyCache.translate(userCode));
                this.save(task);
                //更新收货单下发状态
                receiveMapper.issue(sourceCode,groupCode);
                break;
            }
            case PUTAWAY: {
                //上架
                Putaway putaway = putawayService.getOne(new QueryWrapper<Putaway>().lambda().eq(Putaway::getCode, sourceCode).eq(Putaway::getGroupCode,groupCode));
                if (putaway == null) {
                    throw new ServiceException("任务下发失败，没有找到上架单");
                }
                if (putaway.getIssue() == 1) {
                    throw new ServiceException("任务下发失败，上架单【" + sourceCode + "】已下发");
                }

                //TODO 判断上架单状态
                if (!StrUtil.equals(PutawayStatusEnum.WAITING_PUTAWAY.getValue(), putaway.getStatus())) {
                    // 0:待上架；1：上架中；2：部分上架；3：上架完成；
                    String statusStr = PutawayStatusEnum.translate(putaway.getStatus());

                    throw new ServiceException("任务下发失败，上架单【" + sourceCode + "】" + statusStr);
                }


                List<PutawayItem> putawayItems = putawayItemService.list(new QueryWrapper<PutawayItem>().lambda()
                        .eq(PutawayItem::getPutawayCode, sourceCode)
                        .eq(PutawayItem::getGroupCode,groupCode));
                if (IterUtil.isEmpty(putawayItems)) {
                    throw new ServiceException("任务下发失败，没有找到上架单明细");
                }
                //按容器分组,如果没有容器会分组到key位empty map中
                Map<String, List<PutawayItem>> groupPutawayItem = putawayItems.stream().collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getContainerBarCode()).orElse("empty")));
                groupPutawayItem.entrySet().forEach(e -> {
                    //没有容器的情况下按商品生成上架任务
                    if (!StrUtil.equalsAny(e.getKey(), "empty", "")) {
                        List<PutawayItem> putawayItemList = e.getValue();
                        BigDecimal goodsQuantity = putawayItemList.stream().map(PutawayItem::getReceivedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                        //计算商品种类数量
                        int goodsTypeQuantity = putawayItemList.stream().collect(Collectors.groupingBy(PutawayItem::getGoodsCode)).size();
                        WmsTask task = new WmsTask();
                        String codePrefix = e.getKey() + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
                        task.setCode(codePrefix + OrderIdGeneratorUtil.getAutoIncrementIndex(codePrefix,3));
                        task.setGroupCode(putaway.getGroupCode());
                        task.setTaskType(taskType);
                        task.setWarehouseCode(putaway.getWarehouseCode());
                        task.setGoodsQuantity(goodsQuantity);
                        task.setGoodsTypeQuantity(goodsTypeQuantity);
                        task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                        task.setSourceCode(sourceCode);
                        // 上架时使用 是否有容器: 0 无容器，普通上架；1 有容器，托盘上架  上架单明细containerType 0 周转箱 1 托盘， 周转箱也是普通上架
                        if("0".equals(putawayItemList.get(NUM_ZERO).getContainerType())) {
                            task.setContainer(NUM_ONE);
                        }
                        if ("1".equals(putawayItemList.get(NUM_ZERO).getContainerType())) {
                            task.setContainer(NUM_ZERO);
                        }
                        task.setCreatedBy(userCode);
                        task.setCreatedName(partyCache.translate(userCode));
                        task.setModifiedBy(userCode);
                        task.setModifiedName(partyCache.translate(userCode));
                        this.save(task);
                        //保存任务明细
                        savePutawayTaskItem(putawayItemList, task, userCode);
                        //更新上架登记表任务号
                        putawayRegisterService.updateTaskCode(putawayItemList,groupCode,task.getCode());
                    } else {
                        //所有上架明细，未合并商品
                        List<PutawayItem> putawayItemList = e.getValue();
                        //按商品分组，上架明细
                        Map<String, List<PutawayItem>> listMap = putawayItemList.stream().collect(Collectors.groupingBy(PutawayItem::getGoodsCode));
                        List<WmsTask> wmsTasks = new ArrayList<>();
                        listMap.entrySet().forEach(o -> {
                            Map<String, Object> goods = goodsCache.get(o.getKey());
                            //TODO 校验商品是否存在
                            List<PutawayItem> pValue = o.getValue();
                            //计算商品数量
                            BigDecimal goodsQuantity = pValue.stream().map(PutawayItem::getReceivedQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                            //TODO 此处优化使用SQL批量插入数据
                            WmsTask task = new WmsTask();
                            task.setTaskType(taskType);
                            // 使用商品barCode+日期+流水号
                            String codePrefix = MapUtil.getStr(goods, "barCode") + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
                            task.setCode(codePrefix + OrderIdGeneratorUtil.getAutoIncrementIndex(codePrefix,3));
                            task.setGroupCode(putaway.getGroupCode());
                            task.setWarehouseCode(putaway.getWarehouseCode());
                            task.setGoodsQuantity(goodsQuantity);
                            task.setGoodsTypeQuantity(1);
                            task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                            task.setSourceCode(sourceCode);
                            // 上架时使用 是否有容器: 0 无容器，普通上架；1 有容器，托盘上架
                            task.setContainer(NUM_ZERO);
                            task.setCreatedBy(userCode);
                            task.setCreatedName(partyCache.translate(userCode));
                            task.setModifiedBy(userCode);
                            task.setModifiedName(partyCache.translate(userCode));
                            wmsTasks.add(task);
                            //保存任务明细
                            savePutawayTaskItem(pValue, task, userCode);
                            //更新上架登记表任务号
                            putawayRegisterService.updateTaskCode(pValue,groupCode,task.getCode());
                        });
                        this.saveBatch(wmsTasks);
                    }
                });
                //更新上架单下发状态
                putawayService.updateIssueStatus(sourceCode,groupCode);
                break;
            }
            case PICKING: {
                //拣货
                PickingVO picking = pickingService.getVoByCodeWithAllItem(sourceCode,groupCode);
                if (picking == null) {
                    throw new ServiceException("任务下发失败，没有找到拣货单");
                }
                if (picking.getIssue() == 1) {
                    throw new ServiceException("任务下发失败，拣货单【" + sourceCode + "】已下发");
                }
                //TODO 需要判断收货单状态是否可以下发
                if (!StrUtil.equals(PickingStatusEnum.NOT_PICK.getValue(), picking.getStatus())) {
                    // 0:待拣货；1：拣货中；2：拣货完成；
                    String statusStr = PickingStatusEnum.translate(picking.getStatus());

                    throw new ServiceException("任务下发失败，拣货单【" + sourceCode + "】" + statusStr);
                }
                List<PickingItemVO> pickingItems = picking.getPickingItemVOList();
                //计算商品数量
                BigDecimal goodsQuantity = pickingItems.stream().map(PickingItemVO::getDistributionQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                //计算商品种类数量
                int goodsTypeQuantity = pickingItems.stream().collect(Collectors.groupingBy(PickingItemVO::getGoodsCode)).size();
                WmsTask task = new WmsTask();
                task.setCode(sourceCode + "01");
                task.setGroupCode(picking.getGroupCode());
                task.setWarehouseCode(picking.getWarehouseCode());
                task.setGoodsQuantity(goodsQuantity);
                task.setGoodsTypeQuantity(goodsTypeQuantity);
                task.setTaskType(taskType);
                task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                task.setSourceCode(sourceCode);
                task.setCreatedBy(userCode);
                task.setCreatedName(partyCache.translate(userCode));
                task.setModifiedBy(userCode);
                task.setModifiedName(partyCache.translate(userCode));
                task.setOrderTag(picking.getOrderTag());
                task.setPrepackaged(picking.getPrepackaged());
                this.save(task);
                //更新拣货单下发状态
                pickingService.updateIssueStatus(sourceCode,groupCode);
                break;

            }
            case CHECK: {
                //复核
                Picking picking = pickingService.getOne(new LambdaQueryWrapper<Picking>().eq(Picking::getCode, sourceCode).eq(Picking::getGroupCode,groupCode));
                String wavePickingCode = picking.getWavePickingCode();
                List<Outbound> outboundList = outboundService.list(new LambdaQueryWrapper<Outbound>()
                        .eq(Outbound::getWavePickingCode, wavePickingCode)
                        .eq(Outbound::getGroupCode,groupCode)
                );
                if (outboundList.size() <= 0) {
                    throw new ServiceException("任务下发失败，没有找到出库单");
                }
                if (picking.getOutboundIsIssue() == 1) {
                    throw new ServiceException("任务下发失败，波次号为【" + wavePickingCode + "】的出库单已下发");
                }
                if (!StrUtil.equals(PickingStatusEnum.FINISH_PICK.getValue(),picking.getStatus())) {
                    throw new ServiceException("任务下发失败，拣货单【" + sourceCode + "】的状态不是拣货完成，不能下发出库单");
                }
                long count = outboundList.stream().filter(e -> !StrUtil.equals(OutboundStatusEnum.NOT_RECHECK.getValue(), e.getStatus())).count();
                if ( count > 0) {
                    throw new ServiceException("任务下发失败，出库单状态不全是待复核");
                }
                List<OutboundItem> outboundItems = outboundItemService.list(new LambdaQueryWrapper<OutboundItem>()
                        .eq(OutboundItem::getWavePickingCode, wavePickingCode)
                        .eq(OutboundItem::getGroupCode,groupCode)
                );
                //计算商品数量
                BigDecimal goodsQuantity = outboundItems.stream().map(OutboundItem::getPlanQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                //计算商品种类数量
                int goodsTypeQuantity = outboundItems.stream().collect(Collectors.groupingBy(OutboundItem::getGoodsCode)).size();
                WmsTask task = new WmsTask();
                //拣货单下发的时候用的01，这里出库单还是用的拣货单号，用02开始
                task.setCode(sourceCode + "02");
                task.setGroupCode(picking.getGroupCode());
                task.setWarehouseCode(picking.getWarehouseCode());
                task.setGoodsQuantity(goodsQuantity);
                task.setGoodsTypeQuantity(goodsTypeQuantity);
                task.setTaskType(taskType);
                task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                task.setCreatedBy(userCode);
                task.setCreatedName(partyCache.translate(userCode));
                task.setModifiedBy(userCode);
                task.setModifiedName(partyCache.translate(userCode));
                task.setOrderTag(picking.getOrderTag());
                task.setPrepackaged(picking.getPrepackaged());
                //按单拣货的话，任务中的来源单号为出库单号，其他情况为波次号
                if (OrderTagEnum.QUANTITY.getValue().equals(picking.getOrderTag())) {
                    task.setSourceCode(outboundList.get(NUM_ZERO).getCode());
                } else {
                    task.setSourceCode(wavePickingCode);
                }
                this.save(task);
                //更新出库单下发状态
                pickingService.updateOutboundIssueStatus(wavePickingCode, groupCode);
                break;


//---------------------下面是出库单复核下发的逻辑处理，上面的是在拣货单上面增加一个下发按钮
              /*  //复核
                OutboundVO outbound = outboundService.getVOByCode(sourceCode);
                if (outbound == null) {
                    throw new ServiceException("任务下发失败，没有找到出库单");
                }
                if (outbound.getIssue() == 1) {
                    throw new ServiceException("任务下发失败，出库单【" + sourceCode + "】已下发");
                }
               *//* if (StrUtil.isNotEmpty(outbound.getTemporaryCode())) {
                    throw new ServiceException("任务下发失败，生成波次的出库单不能下发！！！");
                }*//*
                //TODO 需要判断出库单状态是否可以下发
                if (!StrUtil.equals(OutboundStatusEnum.NOT_RECHECK.getValue(), outbound.getStatus())) {
                    // 0:待拣货；1：拣货中；2：拣货完成；
                    String statusStr = OutboundStatusEnum.translate(outbound.getStatus());

                    throw new ServiceException("任务下发失败，出库单【" + sourceCode + "】" + statusStr);
                }
                List<OutboundItemVO> outboundItems = outbound.getOutboundItemVOList();
                //计算商品数量
                BigDecimal goodsQuantity = outboundItems.stream().map(OutboundItemVO::getPlanQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                //计算商品种类数量
                int goodsTypeQuantity = outboundItems.stream().collect(Collectors.groupingBy(OutboundItemVO::getGoodsCode)).size();
                WmsTask task = new WmsTask();
                task.setCode(sourceCode + "01");
                task.setGroupCode(outbound.getGroupCode());
                task.setWarehouseCode(outbound.getWarehouseCode());
                task.setGoodsQuantity(goodsQuantity);
                task.setGoodsTypeQuantity(goodsTypeQuantity);
                task.setTaskType(taskType);
                task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                task.setSourceCode(sourceCode);
                task.setCreatedBy(userCode);
                task.setCreatedName(partyCache.translate(userCode));
                task.setModifiedBy(userCode);
                task.setModifiedName(partyCache.translate(userCode));
                task.setOrderTag(outbound.getOrderTag());
                task.setPrepackaged(outbound.getPrepackaged());
                this.save(task);
                //更新出库单下发状态
                outboundService.updateIssueStatus(sourceCode);
                break;*/

            }
            case MOVE: {
                //移位
                MoveVO move = moveService.getVoByCode(sourceCode, groupCode);
                //TODO 需要判断移位单状态是否可以下发
                if(!StrUtil.equals(MoveStatusEnum.WAIT_MOVE.getValue(),move.getStatus())){
                    String statusStr = MoveStatusEnum.translate(move.getStatus());

                    throw new ServiceException("任务下发失败，移位单【"+sourceCode+"】"+statusStr);
                }

                List<MoveItemVO> moveItems = move.getMoveItemVOList();

                Map<String, List<MoveItemVO>> moveItemsMap = moveItems.stream().collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getLocationName()).orElse("")));
                moveItemsMap.entrySet().forEach(e -> {
                    List<MoveItemVO> moveItemVOList = e.getValue();
                    //计算商品数量
                    BigDecimal goodsQuantity = moveItemVOList.stream().map(MoveItemVO::getMoveQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                    //计算商品种类数量
                    int goodsTypeQuantity = moveItemVOList.stream().collect(Collectors.groupingBy(MoveItemVO::getGoodsCode)).size();
                    WmsTask task = new WmsTask();
                    String codePrefix = e.getKey() + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
                    task.setCode(codePrefix + OrderIdGeneratorUtil.getAutoIncrementIndex(codePrefix,3));
                    task.setGroupCode(move.getGroupCode());
                    if (IterUtil.isNotEmpty(moveItemVOList)) {
                        task.setLocation(moveItemVOList.get(0).getLocation());
                    }
                    task.setTaskType(taskType);
                    task.setWarehouseCode(move.getWarehouseCode());
                    task.setGoodsQuantity(goodsQuantity);
                    task.setGoodsTypeQuantity(goodsTypeQuantity);
                    task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                    task.setSourceCode(sourceCode);
                    task.setCreatedBy(userCode);
                    task.setCreatedName(partyCache.translate(userCode));
                    task.setModifiedBy(userCode);
                    task.setModifiedName(partyCache.translate(userCode));
                    this.save(task);
                    //保存任务明细
                    saveMoveTaskItem(moveItemVOList, task, userCode);
                });
                //更新移位单下发状态
                moveService.updateIssueStatus(sourceCode,groupCode);
                break;

            }
            default: {
                //盘点
                CountingVO counting = countingService.getOneByCode(sourceCode,1,Integer.MAX_VALUE,groupCode);
                //TODO 需要判断出库单状态是否可以下发
                if (!StrUtil.equals(CountingStatusEnum.WAIT_COUNT.getValue(), counting.getStatus())) {
                    // 0:新增；1：待盘点；2：盘点中；3：待审核；4：作废；5：已审核；
                    String statusStr = CountingStatusEnum.translate(counting.getStatus());

                    throw new ServiceException("任务下发失败，盘点单【"+sourceCode+"】"+statusStr);
                }
                //盘点明细
                List<CountingItemVO> countingItems = counting.getCountingItemList();
                //按库位分组
                Map<String, List<CountingItemVO>> countingItemsMap = countingItems.stream().collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getLocation()).orElse("")));
                countingItemsMap.forEach((key, countingItemVOList) -> {

                    BigDecimal goodsQuantity = countingItemVOList.stream().map(CountingItemVO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                    //计算商品种类数量
                    int goodsTypeQuantity = countingItemVOList.stream().collect(Collectors.groupingBy(CountingItemVO::getGoodsCode)).size();
                    WmsTask task = new WmsTask();
                    String codePrefix = locationCache.translate(key) + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
                    task.setCode(codePrefix + OrderIdGeneratorUtil.getAutoIncrementIndex(codePrefix,3));
                    task.setGroupCode(counting.getGroupCode());
                    task.setLocation(key);
                    task.setTaskType(taskType);
                    task.setWarehouseCode(counting.getWarehouseCode());
                    task.setGoodsQuantity(goodsQuantity);
                    task.setGoodsTypeQuantity(goodsTypeQuantity);
                    task.setJobStatus(WmsTaskJobStatusEnum.WAITING);
                    task.setSourceCode(sourceCode);
                    task.setCreatedBy(userCode);
                    task.setCreatedName(partyCache.translate(userCode));
                    task.setModifiedBy(userCode);
                    task.setModifiedName(partyCache.translate(userCode));
                    this.save(task);
                    //保存任务明细
                    saveCountingTaskItem(countingItemVOList, task, userCode);
                });

                //更新盘点单下发状态
                countingService.updateIssueStatus(sourceCode,groupCode);
                break;
            }

        }

        return new AsyncResult(true);
    }


    /**
     * 保存上架任务明细
     *
     * @param putawayItems 上架明细
     * @param task         上架任务
     */
    private void savePutawayTaskItem(List<PutawayItem> putawayItems, WmsTask task, String userCode) {
        List<WmsTaskItem> wmsTaskItems = putawayItems.stream().map(i -> {
            WmsTaskItem wmsTaskItem = new WmsTaskItem();
            wmsTaskItem.setCode(IdUtil.simpleUUID());
            wmsTaskItem.setSourceCode(i.getCode());
            wmsTaskItem.setTaskCode(task.getCode());
            wmsTaskItem.setGroupCode(i.getGroupCode());
            task.setCreatedBy(userCode);
            task.setCreatedName(partyCache.translate(userCode));
            task.setModifiedBy(userCode);
            task.setModifiedName(partyCache.translate(userCode));
            return wmsTaskItem;
        }).collect(Collectors.toList());
        //保存任务明细
        wmsTaskItemService.saveBatch(wmsTaskItems);
    }

    /**
     * 保存盘点任务明细
     *
     * @param countingItems 盘点明细
     * @param task         上架任务
     */
    private void saveCountingTaskItem(List<CountingItemVO> countingItems, WmsTask task, String userCode) {
        List<WmsTaskItem> wmsTaskItems = countingItems.stream().map(i -> {
            WmsTaskItem wmsTaskItem = new WmsTaskItem();
            wmsTaskItem.setCode(IdUtil.simpleUUID());
            wmsTaskItem.setSourceCode(i.getCode());
            wmsTaskItem.setTaskCode(task.getCode());
            wmsTaskItem.setGroupCode(i.getGroupCode());
            task.setCreatedBy(userCode);
            task.setCreatedName(partyCache.translate(userCode));
            task.setModifiedBy(userCode);
            task.setModifiedName(partyCache.translate(userCode));
            return wmsTaskItem;
        }).collect(Collectors.toList());
        //保存任务明细
        wmsTaskItemService.saveBatch(wmsTaskItems);
    }

    /**
     * 保存移位任务明细
     *
     * @param moveItems 移位明细
     * @param task       移位任务
     */
    private void saveMoveTaskItem(List<MoveItemVO> moveItems, WmsTask task, String userCode) {
        List<WmsTaskItem> wmsTaskItems = moveItems.stream().map(i -> {
            WmsTaskItem wmsTaskItem = new WmsTaskItem();
            wmsTaskItem.setCode(IdUtil.simpleUUID());
            wmsTaskItem.setSourceCode(i.getCode());
            wmsTaskItem.setTaskCode(task.getCode());
            wmsTaskItem.setGroupCode(i.getGroupCode());
            task.setCreatedBy(userCode);
            task.setCreatedName(partyCache.translate(userCode));
            task.setModifiedBy(userCode);
            task.setModifiedName(partyCache.translate(userCode));
            return wmsTaskItem;
        }).collect(Collectors.toList());
        //保存任务明细
        wmsTaskItemService.saveBatch(wmsTaskItems);
    }


    /**
     * 指派人员
     *
     * @param taskCode 任务号
     * @param userCode 作业人
     * @param assignBy 指派人
     */
    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public Future<Boolean> assign(String taskCode, String userCode,String assignBy,String groupCode) {
        log.info("任务指派启动线程" + Thread.currentThread().getName() + " 执行异步指派任务：" + taskCode);
        PartyCacheDO party = partyCache.get(userCode);
        if (party == null) {
            throw new ServiceException("任务指派失败，找不到被指派员工【" + userCode + "】");
        }
        WmsTask wmsTask = getOne(new QueryWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode).eq(WmsTask::getGroupCode,groupCode));
        if (wmsTask == null) {
            throw new ServiceException("任务指派失败，找不到任务【" + taskCode + "】");
        }

        if (wmsTask.getJobStatus().equals(WmsTaskJobStatusEnum.COMPLETED)) {
            throw new ServiceException("任务指派失败，任务【" + taskCode + "】已完成");
        }
        if (wmsTask.getJobStatus().equals(WmsTaskJobStatusEnum.WORKING)) {
            throw new ServiceException("任务指派失败，任务【" + taskCode + "】作业中");
        }
        if (wmsTask.getAssign().equals(0)) {
            //更新指派任务
            this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode)
                    .eq(WmsTask::getGroupCode,groupCode)
                    .set(WmsTask::getAssign, 1)
                    .set(WmsTask::getAssignBy, assignBy)
                    .set(WmsTask::getAssignName, partyCache.translate(assignBy))
                    .set(WmsTask::getGmtAssign, DateUtil.now())
                    .set(WmsTask::getOperatorBy, userCode)
                    .set(WmsTask::getOperatorName, party.getName())
            );
        } else {
            throw new ServiceException("任务指派失败，任务【" + taskCode + "】已指派");
        }
        return new AsyncResult(true);
    }

    @Override
    public WmsTaskVO queryPickingTaskByCode(WmsTaskDTO taskDTO) {
        return baseMapper.queryPickingTaskByCode(taskDTO);
    }


    /**
     * 通过任务Code获取任务详情
     *
     * @param code 任务code
     * @return
     */
    @Override
    public WmsTaskVO getByCode(String code) {
        WmsTask wmsTask = this.getOne(new QueryWrapper<WmsTask>().lambda().eq(WmsTask::getCode, code).eq(WmsTask::getGroupCode,UserUtil.getBranchCode()));
        if (wmsTask != null) {
            WmsTaskVO wmsTaskVO = new WmsTaskVO();
            BeanUtil.copyProperties(wmsTask, wmsTaskVO, false);
            Object item = wmsTaskItemService.getTaskDetails(wmsTask.getTaskType(), wmsTask.getCode(), wmsTask.getSourceCode());
            wmsTaskVO.setItems(item);
            return wmsTaskVO;
        }
        return null;
    }

    /**
     * 占用任务（自动指派），如果任务本来是指派给自己的，则不需要处理，
     * 如果任务未被指派，则将任务指派给当前用户；
     * 如果任务已被指派给其他人，则提示；
     *
     * @param wmsTask 任务号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoAssign(WmsTask wmsTask) {
        String currentUserCode = UserUtil.getCode();
        String currentUserName = partyCache.translate(currentUserCode);
        if (ObjectUtil.isNull(wmsTask)) {
            log.error("任务不能为空");
            throw new ServiceException("任务指派失败，找不到任务");
        }
        if (WmsTaskJobStatusEnum.COMPLETED.equals(wmsTask.getJobStatus())) {
            log.error("任务已结束【{}】不能指派",wmsTask.getCode());
            throw new ServiceException("任务【"+wmsTask.getCode()+"】已结束不能指派");
        }
        // 未指派，则自动指派给当前用户
        if(wmsTask.getAssign().equals(NUM_ZERO)){
            boolean actionFlag = this.update(new UpdateWrapper<WmsTask>().lambda()
                    .eq(WmsTask::getGroupCode,UserUtil.getBranchCode())
                    .eq(WmsTask::getCode, wmsTask.getCode())
                    .eq(WmsTask::getAssign, NUM_ZERO)
                    .set(WmsTask::getAssign, NUM_ONE)
                    .set(WmsTask::getOperatorBy, currentUserCode)
                    .set(WmsTask::getOperatorName, currentUserName));
            if (!actionFlag) {
                throw new ServiceException("任务已被指派，无法操作");
            }
        } else {
            if (!currentUserCode.equals(wmsTask.getOperatorBy())) {
                // 剩下的则是任务已被指派，且不是自己的可能
                throw new ServiceException("任务已被指派，无法操作");
            }
        }


    }

    /**
     * 取消任务指派
     *
     * @param taskCode
     */
    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public Future<Boolean> unassign(String taskCode, String groupCode) {
        log.info("任务取消指派启动线程" + Thread.currentThread().getName() + " 执行异步取消指派任务：" + taskCode);
        WmsTask wmsTask = getOne(new QueryWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode).eq(WmsTask::getGroupCode,groupCode));
        if (wmsTask == null) {
            throw new ServiceException("任务指派取消失败，找不到任务【" + taskCode + "】");
        }
        if (WmsTaskJobStatusEnum.COMPLETED.equals(wmsTask.getJobStatus())||WmsTaskJobStatusEnum.WORKING.equals(wmsTask.getJobStatus())) {
            throw new ServiceException("任务【" + taskCode + "】作业中或已完成不能取消");
        }
        this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode)
                .eq(WmsTask::getGroupCode,groupCode)
                .set(WmsTask::getAssign, 0)
                .set(WmsTask::getAssignBy, "")
                .set(WmsTask::getGmtAssign, null)
                .set(WmsTask::getAssignName, "")
                .set(WmsTask::getOperatorBy, "")
                .set(WmsTask::getOperatorName, "")
        );
        return new AsyncResult(true);
    }

    /**
     * @description
     * 更新任务状态为作业中
     * @author xuyang
     * @date 2020/10/27 10:12
     * @param sourceCode:
     **/
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result updateTaskWorkingBySourceCode(String sourceCode){
        // 占用任务，避免多人操作
        WmsTask task = this.getOne(new QueryWrapper<WmsTask>().lambda().eq(WmsTask::getSourceCode, sourceCode).eq(WmsTask::getGroupCode,UserUtil.getBranchCode()));

        log.info("获取任务信息，{}", JSONUtil.toJsonStr(task));
        if(task == null){
            log.error("找不到任务信息，来源标识:{}", sourceCode);
            throw new ServiceException("任务不存在，请确认");
        }
         this.autoAssign(task);
        //更新任务状态为作业中
        this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getSourceCode, sourceCode)
                .eq(WmsTask::getGroupCode,UserUtil.getBranchCode())
                .set(WmsTask::getJobStatus, WmsTaskJobStatusEnum.WORKING)
                .set(WmsTask::getOperatorBy, UserUtil.getCode())
                .set(WmsTask::getOperatorName, partyCache.translate(UserUtil.getCode())));
        return Result.ok();
    }

    /**
     * @param taskCode :
     * @description 更新任务状态为作业中，同时占用任务
     * @author xuyang
     * @date 2020/12/7 10:12
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateTaskWorkingByTaskCode(String taskCode) {
        // 占用任务，避免多人操作
        WmsTask task = this.getOne(new QueryWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode).eq(WmsTask::getGroupCode,UserUtil.getBranchCode()));
        if(task == null){
            return Result.error("任务不存在，请确认");
        }
        this.autoAssign(task);

        //更新任务状态为作业中
        this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode)
                .eq(WmsTask::getGroupCode,UserUtil.getBranchCode())
                .set(WmsTask::getJobStatus, WmsTaskJobStatusEnum.WORKING)
                .set(WmsTask::getOperatorBy, UserUtil.getCode())
                .set(WmsTask::getOperatorName, partyCache.translate(UserUtil.getCode())));
        return Result.ok();
    }

    /**
     * @param putawayCode :
     * @description 根据上架单编码更新作业量
     * @author xuyang
     * @date 2020/10/31 8:18
     **/
    @Override
    public int putawayUpdateJobQuantity(String putawayCode,String groupCode) {
        return this.baseMapper.putawayUpdateJobQuantity(putawayCode, groupCode);
    }

    /**
     * @param code :
     * @description 根据移位单所属任务编码更新作业量
     * @author xuyang
     * @date 2020/12/7 18:18
     **/
    @Override
    public int moveUpdateJobQuantity(String code) {
        return this.baseMapper.moveUpdateJobQuantity(code,UserUtil.getBranchCode());
    }

    /**
     * @param sourceCode :
     * @description 根据拣货单号更新作业量
     * @author xuyang
     * @date 2020/11/4 8:36
     **/
    @Override
    public int pickingUpdateJobQuantity(String sourceCode) {
        return this.baseMapper.pickingUpdateJobQuantity(sourceCode,UserUtil.getBranchCode());
    }

    @Override
    public int updateStatusIfFinishJob(String taskCode, String status) {
        return this.baseMapper.updateStatusIfFinishJob(taskCode, status,UserUtil.getBranchCode());
    }

    /**
     * PDA 查询列表
     * @param wmsTaskDTO
     * @return
     */
    @Override
    public List<WmsTaskVO> queryList4Pda(WmsTaskDTO wmsTaskDTO) {
        String groupCode = UserUtil.getBranchCode();
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StrUtil.isNotEmpty(wmsTaskDTO.getSortField())) {
            wmsTaskDTO.setSortField(CommonUtil.camel2Underline(wmsTaskDTO.getSortField()));
        }
        List<WmsTaskVO> tasks = baseMapper.queryList4Pda(wmsTaskDTO);

        tasks.forEach(e->{
            if(StrUtil.isNotBlank(e.getCustomerCode())){
                e.setCustomerName(customerCache.translate(e.getCustomerCode()));
            }
            if (StrUtil.isNotBlank(e.getSupplierCode())){
                e.setSupplierName(supplierCache.translate(e.getSupplierCode()));
            }
            if (StrUtil.isNotBlank(e.getLocation())) {
                e.setLocationName(locationCache.translate(e.getLocation()));
            }
            //拣货单需要统计订单数量
            if ("PICKING".equals(wmsTaskDTO.getTaskType())) {
                Picking picking = pickingService.getOne(new LambdaQueryWrapper<Picking>().select(Picking::getWavePickingCode)
                        .eq(Picking::getCode, e.getSourceCode())
                        .eq(Picking::getCode,groupCode)
                );
                if(null != picking){
                    int deliveryCount = deliveryService.count(new LambdaQueryWrapper<Delivery>()
                            .eq(Delivery::getWavePickingCode, picking.getWavePickingCode())
                            .eq(Delivery::getGroupCode,groupCode)
                    );
                    e.setDeliveryCount(deliveryCount);
                }
            }

        });
        return tasks;
    }

    /**
     * PDA 查询合计
     * @param wmsTaskDTO
     * @return
     */
    @Override
    public WmsTaskVO queryListSum4Pda(WmsTaskDTO wmsTaskDTO) {
        WmsTaskVO task = baseMapper.queryListSum4Pda(wmsTaskDTO);
        return task;
    }

    /**
     * 判断给定的单号是否有任务且任务还没完全完成； 如果有相关任务且任务未完成，则返回true；
     *
     * @param sourceCode
     * @return
     */
    @Override
    public boolean hasUnFinishTaskForSourceCode(String sourceCode) {
        boolean flag;
        List<WmsTask> tasks = this.list(new QueryWrapper<WmsTask>().lambda().eq(WmsTask::getSourceCode, sourceCode).eq(WmsTask::getGroupCode,UserUtil.getBranchCode()));
        if(IterUtil.isEmpty(tasks)){
            flag = false;
        }else {
            // 如果有任务，则判断任务是否是 待作业或作业中
            flag = tasks.stream().anyMatch(e -> WmsTaskJobStatusEnum.WAITING.equals(e.getJobStatus()) || WmsTaskJobStatusEnum.WORKING.equals(e.getJobStatus()));
        }

        return flag;
    }

    /**
     * PDA 任务中心列表
     *
     * @param wmsTaskDTO
     * @return
     */
    @Override
    public List<WmsTaskVO> pdaTaskList(WmsTaskDTO wmsTaskDTO) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StrUtil.isNotEmpty(wmsTaskDTO.getSortField())) {
            wmsTaskDTO.setSortField(CommonUtil.camel2Underline(wmsTaskDTO.getSortField()));
        }
        return baseMapper.pdaTaskList(wmsTaskDTO);
    }

    /**
     * PDA 任务中心列表合计,包含总数
     *
     * @param wmsTaskDTO
     * @return
     */
    @Override
    public WmsTaskVO pdaTaskListSum(WmsTaskDTO wmsTaskDTO) {
        return baseMapper.pdaTaskListSum(wmsTaskDTO);
    }

    /**
     * 查询各订单标识对应的任务信息
     */
    @Override
    public List<WmsTaskVO> queryTaskInfoByOrderTag(WmsTaskDTO wmsTaskDTO) {
        wmsTaskDTO.setGroupCode(UserUtil.getBranchCode());
        return baseMapper.queryTaskInfoByOrderTag(wmsTaskDTO);
    }

    /**
     * 根据单号结束任务
     *
     * @param sourceCode 单号
     * @param userCode 操作人code
     * @param userName 操作人名称
     * @author liuxr
     * @date 2021/5/15 8:47
     * @return
     */
    @Override
    public int endTask(String sourceCode,String userCode,String userName) {
        return baseMapper.endTask(sourceCode,userCode,userName,UserUtil.getBranchCode());
    }


    /**
     * 根据单号结束任务
     *
     * @param sourceCode 单号
     * @param userCode 操作人code
     * @param userName 操作人名称
     * @author liuxr
     * @date 2021/5/15 8:47
     * @return
     */
    @Override
    public int endTaskYb(String sourceCode,String userCode,String userName,String groupCode) {
        return baseMapper.endTask(sourceCode,userCode,userName,groupCode);
    }


    /**
     * 检查任务是否完成
     *
     * @param sourceCode
     * @return boolean
     * @author liuxr
     * @date 2021/5/29 12:19
     */
    @Override
    public boolean isCompleted(String sourceCode) {
        WmsTask task = this.getOne(Wrappers.lambdaQuery(WmsTask.class).select(WmsTask::getJobStatus)
                .eq(WmsTask::getSourceCode,sourceCode));
        if(null==task){
            log.error("来源单号【{}】找不到任务信息",sourceCode);
            throw new ServiceException("来源单号【"+sourceCode+"】找不到任务信息");
        }
        return task.getJobStatus().equals(WmsTaskJobStatusEnum.COMPLETED);
    }

    /**
     * 根据来源单号更新任务数量
     * @author rfwang
     * @date 2022/1/25
     * @param sourceCode
     * @param quantity
     * @return boolean
     */
    @Override
    public boolean updateJobQuantity(String sourceCode, BigDecimal quantity){
        return this.update(new LambdaUpdateWrapper<WmsTask>()
                .eq(WmsTask::getSourceCode, sourceCode)
                .eq(WmsTask::getGroupCode,UserUtil.getBranchCode())
                .setSql("job_quantity = job_quantity +" + quantity));
    }

    /**
     * 重新构建任务单号，通过波次号查询查询任务号
     * @author rfwang
     * @date 2022/3/15
     * @param wmsTaskDTO
     */
    @Override
    public void reconstructParams(WmsTaskDTO wmsTaskDTO){
        if (StrUtil.isEmpty(wmsTaskDTO.getCode())) {
            return;
        }
        //判断是否是波次号
        boolean flag ;
        flag = wmsTaskDTO.getCode().startsWith("BC");
        String code = wmsTaskDTO.getCode();
        if (flag) {
            Picking picking = pickingService.getOne(new LambdaQueryWrapper<Picking>().select(Picking::getCode).eq(Picking::getWavePickingCode, wmsTaskDTO.getCode())
                    .eq(Picking::getGroupCode, wmsTaskDTO.getGroupCode()));
            if (null != picking) {
                code = picking.getCode() + "02";
            }
            wmsTaskDTO.setCode(code);
        }
    }

    /**
     * 重新构建任务单号
     * @author rfwang
     * @date 2022/3/15
     * @param wavePickingCode
     * @param groupCode
     */
    @Override
    public void updateTaskStatusByWaybillCheck(String wavePickingCode,String groupCode,BigDecimal recheckQuantity,boolean updateRecheckNow){
        Picking picking = pickingService.getOne(new LambdaQueryWrapper<Picking>().select(Picking::getCode).eq(Picking::getWavePickingCode, wavePickingCode).eq(Picking::getGroupCode, groupCode));
        String taskCode = picking.getCode() + "02";
        if (updateRecheckNow) {
            this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode)
                    .eq(WmsTask::getGroupCode, groupCode)
                    .setSql("job_quantity = job_quantity +" + recheckQuantity));
            return;
        }
        List<String> statuses = new ArrayList<String>(Arrays.asList(DeliveryStatusEnum.UN_DELIVERY.getValue(), DeliveryStatusEnum.DELIVERYING.getValue(), DeliveryStatusEnum.DELIVERIED.getValue()));
        //更新下发任务，如果下发，将下发任务更新为已完成
        int finishWaveFlag = deliveryService.count(new LambdaQueryWrapper<Delivery>()
                .eq(Delivery::getWavePickingCode, wavePickingCode)
                .eq(Delivery::getIsCancel, NUM_ZERO)
                .eq(Delivery::getGroupCode, groupCode)
                .in(Delivery::getStatus, statuses));
        int totalDelivery = deliveryService.count(new LambdaQueryWrapper<Delivery>()
                .eq(Delivery::getWavePickingCode, wavePickingCode)
                .eq(Delivery::getIsCancel, NUM_ZERO)
                .eq(Delivery::getGroupCode, groupCode));

        if (finishWaveFlag == totalDelivery) {
            //更新任务状态
            this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode)
                    .eq(WmsTask::getGroupCode,groupCode)
                    .set(WmsTask::getJobStatus, WmsTaskJobStatusEnum.COMPLETED));
        } else {
            this.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getCode, taskCode)
                    .eq(WmsTask::getGroupCode, groupCode)
                    .setSql("job_quantity = job_quantity +" + recheckQuantity));
        }
    }

}
